package com.guosen.zebra.framework.starter.config.internal;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.guosen.zebra.framework.basic.http.OKHttpClientUtil;
import com.guosen.zebra.framework.starter.config.exception.ZebraConfigException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

@Slf4j
public class ZebraConfigHttpClient {

    private ZebraConfigHttpClient() {}

    /**
     * JSON类型
     */
    public static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");

    /**
     * http协议客户端
     */
    private static final OkHttpClient HTTP_CLIENT = OKHttpClientUtil.getHttpClient();

    /**
     * https客户端，忽略证书
     */
    private static final OkHttpClient UNSAFE_HTTPS_CLIENT = OKHttpClientUtil.getUnsafeHttpsClient();

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();


    public static JsonNode get(String url, Map<String, String> headers, Map<String, String> parameters)
            throws ZebraConfigException {
        Request.Builder builder = new Request.Builder();
        setHeaders(headers, builder);
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();

        for(Map.Entry<String, String> parameter : parameters.entrySet()) {
            urlBuilder.addQueryParameter(parameter.getKey(), parameter.getValue());
        }

        builder.url(urlBuilder.build());
        return doInvoke(builder.build(), url);
    }

    private static void setHeaders(Map<String, String> headers, Request.Builder builder) {
        for (Map.Entry<String, String> header : headers.entrySet()) {
            builder.header(header.getKey(), header.getValue());
        }
    }

    private static JsonNode doInvoke(Request request, String url) throws ZebraConfigException {
        JsonNode result = null;
        try (Response response = getHttpClient(url).newCall(request).execute();
             ResponseBody responseBody = response.body()){
            if (responseBody != null) {
                String respString = responseBody.string();
                if (StringUtils.isNotBlank(respString)) {
                    result = OBJECT_MAPPER.readTree(respString);
                }
            }
        } catch (Exception e) {
            log.error("Failed to invoke {}, error message : {}", url, e.getMessage(), e);
            throw new ZebraConfigException("500", e.getMessage());
        }
        return result;
    }

    private static OkHttpClient getHttpClient(String url) {
        boolean isHttps = StringUtils.startsWithIgnoreCase(url, "https");
        return isHttps ? UNSAFE_HTTPS_CLIENT : HTTP_CLIENT;
    }
}
